
module mycpu_shifter (
    input      [31:0] shiftDataIn,
    input             shiftDirection,
    input      [4:0]  shiftDistance,
    output     [31:0] shiftResultLogical,
    output     [31:0] shiftResultArithmetic
  );

    wire [31:0] data = shiftDataIn;
    wire        dir = shiftDirection;
    wire [4:0]  shift = shiftDistance;

  wire [31:0] logical     = shift[4] ? (dir == 0 ? {   logical3[31-16:0],16'b0} : {                  16'b0,   logical3[31:16]}) :    logical3[31: 0];
  wire [31:0] logical3    = shift[3] ? (dir == 0 ? {   logical2[31- 8:0], 8'b0} : {                   8'b0,   logical2[31: 8]}) :    logical2[31: 0];
  wire [31:0] logical2    = shift[2] ? (dir == 0 ? {   logical1[31- 4:0], 4'b0} : {                   4'b0,   logical1[31: 4]}) :    logical1[31: 0];
  wire [31:0] logical1    = shift[1] ? (dir == 0 ? {   logical0[31- 2:0], 2'b0} : {                   2'b0,   logical0[31: 2]}) :    logical0[31: 0];
  wire [31:0] logical0    = shift[0] ? (dir == 0 ? {       data[31- 1:0], 1'b0} : {                   1'b0,       data[31: 1]}) :        data[31: 0];
  
  wire [31:0] arithmetic  = shift[4] ? (dir == 0 ? {arithmetic3[31-16:0],16'b0} : {{(16){arithmetic3[31]}},arithmetic3[31:16]}) : arithmetic3[31: 0];
  wire [31:0] arithmetic3 = shift[3] ? (dir == 0 ? {arithmetic2[31- 8:0], 8'b0} : {{( 8){arithmetic2[31]}},arithmetic2[31: 8]}) : arithmetic2[31: 0];
  wire [31:0] arithmetic2 = shift[2] ? (dir == 0 ? {arithmetic1[31- 4:0], 4'b0} : {{( 4){arithmetic1[31]}},arithmetic1[31: 4]}) : arithmetic1[31: 0];
  wire [31:0] arithmetic1 = shift[1] ? (dir == 0 ? {arithmetic0[31- 2:0], 2'b0} : {{( 2){arithmetic0[31]}},arithmetic0[31: 2]}) : arithmetic0[31: 0];
  wire [31:0] arithmetic0 = shift[0] ? (dir == 0 ? {       data[31- 1:0], 1'b0} : {{( 1){       data[31]}},       data[31: 1]}) :        data[31: 0];


  assign shiftResultLogical = logical;
  assign shiftResultArithmetic = arithmetic;

endmodule
